home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 45
/
Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso
/
Aminet
/
gfx
/
x11
/
x3270_3_2_16.lha
/
amiga_src
/
x3270if.c
< prev
next >
Wrap
C/C++ Source or Header
|
2009-02-19
|
7KB
|
348 lines
/*
* Copyright 1995, 1996, 1999, 2000 by Paul Mattes.
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*/
/*
* Script interface utility for x3270.
*
* Accesses an x3270 command stream on the file descriptors defined by the
* environment variables X3270OUTPUT (output from x3270, input to script) and
* X3270INPUT (input to x3270, output from script).
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define IBS 1024
extern int optind;
extern char *optarg;
static char *me;
static int verbose = 0;
static char buf[IBS];
static void iterative_io(void);
static void single_io(int fn, char *cmd);
static void
usage(void)
{
(void) fprintf(stderr, "\
usage: %s [-v] action[(param[,...])]\n\
%s [-v] -s field\n\
%s -i\n", me, me, me);
exit(2);
}
/* Get a file descriptor from the environment. */
static int
fd_env(const char *name)
{
char *fdname;
int fd;
fdname = getenv(name);
if (fdname == (char *)NULL) {
(void) fprintf(stderr, "%s: %s not set in the environment\n",
me, name);
exit(2);
}
fd = atoi(fdname);
if (fd <= 0) {
(void) fprintf(stderr, "%s: invalid value '%s' for %s\n", me,
fdname, name);
exit(2);
}
return fd;
}
int
main(int argc, char *argv[])
{
int c;
int fn = -1;
char *ptr;
int iterative = 0;
/* Identify yourself. */
if ((me = strrchr(argv[0], '/')) != (char *)NULL)
me++;
else
me = argv[0];
/* Parse options. */
while ((c = getopt(argc, argv, "is:v")) != -1) {
switch (c) {
case 'i':
if (fn != -1)
usage();
iterative++;
break;
case 's':
if (fn != -1 || iterative)
usage();
fn = (int)strtol(optarg, &ptr, 0);
if (ptr == optarg || *ptr != '\0' || fn < 0) {
(void) fprintf(stderr,
"%s: Invalid field number: '%s'\n", me,
optarg);
usage();
}
break;
case 'v':
verbose++;
break;
default:
usage();
break;
}
}
/* Validate positional arguments. */
if (fn != -1 || iterative) {
if (optind != argc)
usage();
} else {
if (optind != argc - 1)
usage();
}
/* Ignore broken pipes. */
(void) signal(SIGPIPE, SIG_IGN);
/* Do the I/O. */
if (!iterative) {
single_io(fn, argv[optind]);
} else {
iterative_io();
}
return 0;
}
/* Do a single command, and interpret the results. */
static void
single_io(int fn, char *cmd)
{
FILE *inf = NULL, *outf = NULL;
char status[IBS] = "";
int xs = -1;
/* Verify the environment and open files. */
inf = fdopen(fd_env("X3270OUTPUT"), "r");
if (inf == (FILE *)NULL) {
perror("x3270if: input: fdopen($X3270OUTPUT)");
exit(2);
}
outf = fdopen(fd_env("X3270INPUT"), "w");
if (outf == (FILE *)NULL) {
perror("x3270if: output: fdopen($X3270INPUT)");
exit(2);
}
/* Speak to x3270. */
if (fprintf(outf, "%s\n", (fn == -1)? cmd: "") < 0 ||
fflush(outf) < 0) {
perror("x3270if: printf");
exit(2);
}
if (verbose)
(void) fprintf(stderr, "i+ out %s\n",
(fn == -1) ? cmd : "");
/* Get the answer. */
while (fgets(buf, IBS, inf) != (char *)NULL) {
int sl = strlen(buf);
if (sl > 0 && buf[sl-1] == '\n')
buf[--sl] = '\0';
if (verbose)
(void) fprintf(stderr, "i+ in %s\n", buf);
if (!strcmp(buf, "ok")) {
(void) fflush(stdout);
xs = 0;
break;
} else if (!strcmp(buf, "error")) {
(void) fflush(stdout);
xs = 1;
break;
} else if (!strncmp(buf, "data: ", 6)) {
if (printf("%s\n", buf+6) < 0) {
perror("x3270if: printf");
exit(2);
}
} else
(void) strcpy(status, buf);
}
/* If fgets() failed, so should we. */
if (xs == -1) {
if (feof(inf))
(void) fprintf(stderr,
"x3270if: input: unexpected EOF\n");
else
perror("x3270if: input");
exit(2);
}
if (fflush(stdout) < 0) {
perror("x3270if: fflush");
exit(2);
}
/* Print status, if that's what they want. */
if (fn != -1) {
char *sf = (char *)NULL;
char *sb = status;
do {
if (!fn--)
break;
sf = strtok(sb, " \t");
sb = (char *)NULL;
} while (sf != (char *)NULL);
if (printf("%s\n", (sf != (char *)NULL) ? sf : "") < 0) {
perror("x3270if: printf");
exit(2);
}
}
if (fflush(stdout) < 0) {
perror("x3270if: fflush");
exit(2);
}
exit(xs);
}
/* Act as a passive pipe between 'expect' and x3270. */
static void
iterative_io(void)
{
# define N_IO 2
struct {
const char *name;
int rfd, wfd;
char buf[IBS];
int offset, count;
} io[N_IO]; /* [0] is program->x3270, [1] is x3270->program */
fd_set rfds, wfds;
int fd_max = 0;
int i;
#ifdef DEBUG
if (verbose) {
freopen("/tmp/x3270if.dbg", "w", stderr);
setlinebuf(stderr);
}
#endif
/* Get the x3270 file descriptors. */
io[0].name = "program->x3270";
io[0].rfd = fileno(stdin);
io[0].wfd = fd_env("X3270INPUT");
io[1].name = "x3270->program";
io[1].rfd = fd_env("X3270OUTPUT");
io[1].wfd = fileno(stdout);
for (i = 0; i < N_IO; i++) {
if (io[i].rfd > fd_max)
fd_max = io[i].rfd;
if (io[i].wfd > fd_max)
fd_max = io[i].wfd;
(void) fcntl(io[i].rfd, F_SETFL,
fcntl(io[i].rfd, F_GETFL, 0) | O_NDELAY);
(void) fcntl(io[i].wfd, F_SETFL,
fcntl(io[i].wfd, F_GETFL, 0) | O_NDELAY);
io[i].offset = 0;
io[i].count = 0;
}
fd_max++;
for (;;) {
int rv;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
for (i = 0; i < N_IO; i++) {
if (io[i].count) {
FD_SET(io[i].wfd, &wfds);
#ifdef DEBUG
if (verbose)
(void) fprintf(stderr,
"enabling output %s %d\n",
io[i].name, io[i].wfd);
#endif
} else {
FD_SET(io[i].rfd, &rfds);
#ifdef DEBUG
if (verbose)
(void) fprintf(stderr,
"enabling input %s %d\n",
io[i].name, io[i].rfd);
#endif
}
}
if ((rv = select(fd_max, &rfds, &wfds, (fd_set *)NULL,
(struct timeval *)NULL)) < 0) {
perror("x3270if: select");
exit(2);
}
if (verbose)
(void) fprintf(stderr, "select->%d\n", rv);
for (i = 0; i < N_IO; i++) {
if (io[i].count) {
if (FD_ISSET(io[i].wfd, &wfds)) {
rv = write(io[i].wfd,
io[i].buf + io[i].offset,
io[i].count);
if (rv < 0) {
(void) fprintf(stderr,
"x3270if: write(%s): %s",
io[i].name,
strerror(errno));
exit(2);
}
io[i].offset += rv;
io[i].count -= rv;
#ifdef DEBUG
if (verbose)
(void) fprintf(stderr,
"write(%s)->%d\n",
io[i].name, rv);
#endif
}
} else if (FD_ISSET(io[i].rfd, &rfds)) {
rv = read(io[i].rfd, io[i].buf, IBS);
if (rv < 0) {
(void) fprintf(stderr,
"x3270if: read(%s): %s",
io[i].name, strerror(errno));
exit(2);
}
if (rv == 0)
exit(0);
io[i].offset = 0;
io[i].count = rv;
#ifdef DEBUG
if (verbose)
(void) fprintf(stderr,
"read(%s)->%d\n", io[i].name, rv);
#endif
}
}
}
}